home *** CD-ROM | disk | FTP | other *** search
- /* xserver.c: show pictures of the fitted characters on an X display.
-
- Copyright (C) 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "config.h"
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xatom.h>
- #include <X11/Xaw/Label.h>
- #include <X11/Xaw/Viewport.h>
-
- #include "xserver.h"
-
- /* For the resource database. */
- #define CLASS_NAME "Limn"
-
- /* The root of the widget hierarchy. */
- static Widget top_level;
-
- /* The connection to the X server. */
- static Display *display;
-
- /* Where we draw the pictures. */
- static Widget canvas_widget;
-
- /* The messages we recognize. */
- Atom foserver_exit_atom, foserver_update_pixmap_atom;
-
- /* This property contains an identification string for the server.
- The string name is in xserver.h. */
- Atom foserver_identity_atom;
-
- /* The type of the `data' member in a ClientMessage event. */
- typedef union
- {
- char b[20];
- short s[10];
- long l[5];
- } message_data_type;
-
- static void dispatch_message (Atom, message_data_type);
- static void foserver_exit (void);
- static void foserver_update_pixmap (Pixmap);
- static void message_handler (Widget, XEvent *, String *, Cardinal *);
-
- void
- #ifdef STANDALONE_SERVER
- main (int argc, char *argv[])
- {
- unsigned window_size;
- string identity; /* This will be the contents of `identity_atom'. */
- #else /* not STANDALONE_SERVER */
- start_server (unsigned window_size, string identity)
- {
- #endif /* not STANDALONE_SERVER */
-
- XTextProperty textP;
- Widget viewport_widget;
- int zero = 0;
-
- /* This routine will intercept messages we get. */
- XtActionsRec actions[] = { { "MessageHandler", message_handler } };
-
- /* Here we assume that all the characters will fit in an em square.
- (We make further assumptions below.) The TFM format guarantees
- that the design size is not negative. Values in the resource
- database override this. These initial values are only useful if we
- are not standalone, but we reassign just below if we are
- standalone. */
- Arg geometry_args[]
- = { { XtNheight, window_size },
- { XtNwidth, window_size },
- };
-
- #ifdef STANDALONE_SERVER
- if (argc == 3)
- {
- window_size = atou (argv[1]);
- geometry_args[0].value = geometry_args[1].value = window_size;
- identity = argv[2];
- }
- else
- {
- fprintf (stderr, "Usage: %s window-size identity.\n", argv[0]);
- exit (0);
- }
- #endif /* STANDALONE_SERVER */
-
- /* We have no fallback resources, and we've already parsed the args. */
- top_level = XtInitialize (NULL, CLASS_NAME, NULL, 0, &zero, NULL);
-
- viewport_widget
- = XtCreateManagedWidget ("viewport", viewportWidgetClass, top_level,
- NULL, 0);
- canvas_widget
- = XtCreateManagedWidget ("canvas", labelWidgetClass, viewport_widget,
- geometry_args, XtNumber (geometry_args));
-
- XtAddActions (actions, XtNumber (actions));
-
- XtRealizeWidget (top_level);
-
- display = XtDisplay (top_level);
-
- foserver_exit_atom = XInternAtom (display, FOSERVER_EXIT_ATOM, False);
- foserver_update_pixmap_atom
- = XInternAtom (display, FOSERVER_UPDATE_PIXMAP_ATOM, False);
-
- /* Get the identity atom number. Create it if it doesn't exist. */
- foserver_identity_atom
- = XInternAtom (display, FOSERVER_IDENTITY_ATOM, False);
-
- textP.value = (unsigned char *) identity; /* Set value. */
- textP.encoding = XA_STRING;
- textP.format = 8;
- textP.nitems = strlen (identity);
- XSetTextProperty (display, XtWindow (canvas_widget), &textP,
- foserver_identity_atom);
-
- /* Process events forever. */
- XtMainLoop ();
- }
-
-
- static void
- message_handler (Widget w, XEvent *event, String *params, Cardinal *n_params)
- {
- switch (event->type)
- {
- case ClientMessage:
- {
- XClientMessageEvent m = event->xclient;
- message_data_type d;
-
- /* Because two union types are never equivalent, and the X
- library does not define a type for the data part of the
- event, we must copy the data. */
- memcpy (&d, &(m.data), sizeof (d.b));
-
- dispatch_message (m.message_type, d);
- break;
- }
-
- default:
- FATAL1 ("foserver: Unexpected event (type %d)", event->type);
- }
- }
-
-
- /* Call the appropriate routine for the atom A, or give an error. */
-
- static void
- dispatch_message (Atom a, message_data_type data)
- {
- if (a == foserver_exit_atom)
- foserver_exit ();
-
- else if (a == foserver_update_pixmap_atom)
- foserver_update_pixmap (data.l[0]);
-
- else
- WARNING1 ("foserver: Unknown message `%s'", XGetAtomName (display, a));
- }
-
- /* Shut down. */
-
- static void
- foserver_exit ()
- {
- XCloseDisplay (display);
- exit (0);
- }
-
-
- /* Show a new pixmap. */
-
- static void
- foserver_update_pixmap (Pixmap p)
- {
- Arg label_args[]
- = { { XtNbitmap, p },
- };
-
- /* Call XtSetValues only after drawing everything, since it
- doesn't particularly matter if what we draw is visible as we
- go. (In general, because of the asynchronicity of the server,
- it wouldn't be, anyway.) */
- XtSetValues (canvas_widget, label_args, XtNumber (label_args));
- }
-